﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Office.Interop.Excel;
using System.Linq.Expressions;

namespace TpExtensions {

    public static class Extensions {

        #region Members

        public static List<string> TpFahrzeuge = new List<string> { "A5", "A6", "A7", "B1", "C9", "Di", "El", "Fb", "F3", "F4", "F7", "F8", "F5", "F6", "Lf", "Ae", "Ml", "Pn", "Pr", "S", };
        public static List<string> TpUser = new List<string> {"Aa", "Bb","Cc", "Al", "As", "At", "Dl", "Es", "Ew", "Gl", "Gz", "Kb", "Ks", "Ma", "Md", "Mh", "Na", "Nd", "Nv", "Pk", "Pn", "Rj", "Rk", "Tz", "Wk", "Wl", "Wz", "Zj" };
        public const string tpDateFormat = "yy-MM-dd";
        public const string tpDateFormatExtern = "yyyy-MM-dd";
        public const string tpTimeFormat = "HH:mm:ss";
        public const double tpColumnWidth = 66.0;
        public const string tpFontNormal = "Stratum2 Regular";
        public const string tpFontBold = "Univers LT Std 47 Cn Lt";
        public const string tpExcelCalculationTemplate = @"H:\Vorlagen\Ka\Ka.xltm";
        public const string tpStartAddress = "1230 Wien, Liesinger Flurgasse 3";

        public enum JobStatus : short {
            JobEvidenz = 0,
            Durchgeführt = 1,
            Exportiert = 2
        }

        public enum DocExt : int {
            [Extensions.StringValue(".docx")]
            DocX = 1,
            [Extensions.StringValue(".xlsm")]
            XlsM = 2,
            [Extensions.StringValue(".xlsx")]
            XlsX = 3

        }


        public enum DocType : int {
            [Extensions.StringValue("vk")]
            Verkauf = 1,
            [Extensions.StringValue("df")]
            Durchführung = 2,
            [Extensions.StringValue("ag")]
            Angebot = 3,
            [Extensions.StringValue("ab")]
            Auftragsbestaetigung = 4,
            [Extensions.StringValue("ap")]
            Abnahmeprotokoll = 5,
            [Extensions.StringValue("ku")]
            Kundenkorrespondenz = 6,
            [Extensions.StringValue("li")]
            Lieferantenkorrespondenz = 7,
            [Extensions.StringValue("pb")]
            Projektbericht = 8,
            [Extensions.StringValue("te")]
            Technik = 9,
            [Extensions.StringValue("tk")]
            Telekonkontakt = 10,
            [Extensions.StringValue("re")]
            Rechnung = 11,
            [Extensions.StringValue("mail")]
            Mail = 12
        }

        public enum tpLeistungsbericht : byte {
            [Extensions.StringValue("Leistungsbericht Geschäftsfall")]
            LeistungsberichtGeschäftsfall = 1,
            [Extensions.StringValue("Leistungsbericht Lohnfertigung")]
            LeistungsberichtLohnfertigung = 2
        }

        public enum TpSex : byte {
            [Extensions.StringValue("Herr")]
            Man = 1,
            [Extensions.StringValue("Frau")]
            Woman = 2,
            [Extensions.StringValue("Firma")]
            Company = 3
        }

        public enum TelType : int {
            Nothing = 0,
            Interessent = 1,
            Reparaturanfrage = 2,
            Nachfrage = 3,
            Service = 4,
            Sonstiges = 5
        }

        public enum TelStatus : int {
            [Extensions.StringValue("Nothing")]
            Nothing = 0,
            [Extensions.StringValue("Offen")]
            Offen = 1,
            [Extensions.StringValue("In Arbeit")]
            InArbeit = 2,
            [Extensions.StringValue("Erledigt")]
            Erledigt = 3

        }

        public enum TpStatus : int {
            [Extensions.StringValue("Angebot")]
            Angebot = 1,
            [Extensions.StringValue("Verkauf")]
            Verkauf = 2,
            [Extensions.StringValue("Kunde")]
            Kunde = 3,
            [Extensions.StringValue("Verloren")]
            Verloren = 4
        }

        public enum TpKuerzel : int {
            [Extensions.StringValue("Admi")]
            Admi = 1,
            [Extensions.StringValue("Kund")]
            Kund = 2,
            [Extensions.StringValue("Lief")]
            Lief = 3,
            [Extensions.StringValue("Mark")]
            Mark = 4,
            [Extensions.StringValue("Rewe")]
            Rewe = 5,
            [Extensions.StringValue("Verk")]
            Verk = 6,
            [Extensions.StringValue("Verl")]
            Verl = 7
        }

        public enum SheetType : int {
            [Extensions.StringValue("Unbekannt")] //***
            Unbekannt = 0,
            [Extensions.StringValue("Kalkulation")] //***
            Kalkulation = 1,
            [Extensions.StringValue("Angebot")] //***
            Angebot = 2,
            [Extensions.StringValue("Projektbericht")] //***
            Projektbericht = 3,
            [Extensions.StringValue("Abnahmeprotokoll")] //***
            Abnahmeprotokoll = 4,
            [Extensions.StringValue("Auftragsbestaetigung")] //***
            Auftragsbestaetigung = 5,
            [Extensions.StringValue("Abrechnung")] //***
            Abrechnung = 6,
            [Extensions.StringValue("Lieferschein")] //***
            Lieferschein = 7,
            [Extensions.StringValue("Rechnung")] //***
            Rechnung = 8,
            [Extensions.StringValue("EverySheet")] //***
            EverySheet = 99
        }

        public enum tpContent {
            AllJobs = 1,
            ProjectJobs = 2,
            InternJobs = 3
        }

        public enum tpSorting {
            Date = 1,
            Area = 2,
            Hour = 3
        }

        public enum tpSortOrder {
            Up = 1,
            Down = 2
        }

        public enum tpShow {
            Area = 1,
            List = 3
        }

        public enum tpFont {
            Bold = 1,
            Regular = 2
        }

        public enum tpJobType {
            Definiert = 1,
            Alternativ = 2
        }

        public enum tpPaymentMode : int {
            [Extensions.StringValue("bar bei Abholung ohne Skontoabzug")]
            BarBeiAbholung = 1,
            [Extensions.StringValue("bar bei Abholung abzüglich 2 % Skonto")]
            BarBeiAbholungMinusSkonto = 2,
            [Extensions.StringValue("per Nachnahme")]
            PerNachnahme = 3
        }

        public enum tpWindowType : int {
            Angebot = 1,
            Auftragsbestätigung = 2,
            Rechnung = 3,
            Mahnung = 4,
            Mail = 5,
            Korrepondenz = 6
        }

        #endregion

        #region Attributes

        public class StringValueAttribute : Attribute {

            #region Properties

            /// <summary>
            /// Holds the stringvalue for a value in an enum.
            /// </summary>
            public string StringValue { get; protected set; }

            #endregion

            #region Constructor

            /// <summary>
            /// Constructor used to init a StringValue Attribute
            /// </summary>
            /// <param name="value"></param>
            public StringValueAttribute(string value) {
                this.StringValue = value;
            }

            #endregion

        }

        #endregion

        #region Enum

        public static string GetStringValue(this Enum value) {
            // Get the type
            Type type = value.GetType();

            // Get fieldinfo for this type
            FieldInfo fieldInfo = type.GetField(value.ToString());

            // Get the stringvalue attributes
            StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
                typeof(StringValueAttribute), false) as StringValueAttribute[];

            // Return the first if there was a match.
            return attribs.Length > 0 ? attribs[0].StringValue : null;
        }

        #endregion

        #region String

        public static string AddSpace(this string value) {
            return (value == null ? "" : value + " ");
        }

        public static bool IsDate(this string value) {
            bool isDate = false;
            DateTime dt;
            try {
                dt = DateTime.Parse(value);
                isDate = true;
            } catch {
                isDate = false;
            }
            return isDate;
        }

        public static bool IsNumeric(this string value, System.Globalization.NumberStyles NumberStyle) {
            Double result;
            return Double.TryParse(value, NumberStyle,
                System.Globalization.CultureInfo.CurrentCulture, out result);
        }

        public static string Left(this string text, byte length) {
            if (length < 0)
                throw new ArgumentOutOfRangeException("length", length, "length must be > 0");
            else if (length == 0 || text.Length == 0)
                return "";
            else if (text.Length <= length)
                return text;
            else
                return text.Substring(0, length);
        }

        public static string Right(this string original, int numberCharacters) {
            if (original == null | original == String.Empty) {
                return "";
            }
            return original.Substring(original.Length - numberCharacters);
        }

        public static string FirstCharBig(this string original) {
            string firstBig = original.Substring(0, 1).ToUpper() + original.Substring(1, original.Length - 1).ToLower();
            return firstBig;
        }

        #endregion

        #region Functions
                        
        public static bool isNumeric(string val, System.Globalization.NumberStyles NumberStyle) {
            Double result;
            return Double.TryParse(val, NumberStyle,
                System.Globalization.CultureInfo.CurrentCulture, out result);
        }

        public static string Left(string text, int length) {
            if (length < 0)
                throw new ArgumentOutOfRangeException("length", length, "length must be > 0");
            else if (length == 0 || text.Length == 0)
                return "";
            else if (text.Length <= length)
                return text;
            else
                return text.Substring(0, length);
        }

        public static string Mid(string param, int startIndex, int length) {
            //start at the specified index in the string ang get N number of
            //characters depending on the lenght and assign it to a variable
            string result = param.Substring(startIndex, length);
            //return the result of the operation
            return result;
        }

        public static string Mid(string param, int startIndex) {
            //start at the specified index and return all characters after it
            //and assign it to a variable
            string result = param.Substring(startIndex);
            //return the result of the operation
            return result;
        }

        public static T Nz<T>(T Value, T Replacement) {

            try {
                if (Value != null) {
                    if (Value.GetType() != Replacement.GetType()) {
                        if (Replacement.GetType().ToString().Contains("String")) {
                            object ret = Value.ToString();
                            return (T)ret;
                        }
                    }
                    return Value;
                } else {
                    return Replacement;
                }
            } catch (Exception e) {
                Debug.Print(e.ToString());
                return Replacement;
            }

        }

        #endregion

        #region Methods

        public static void AddDictionayFields(Dictionary<string, string> myDict, string tKey, object tValue) {
            AddDictionayFields(myDict, tKey, tValue, null);
        }

        public static void AddDictionayFields(Dictionary<string, string> myDict, string tKey, object tValue, object defaultValue) {
            if (tValue != null) {
                myDict.Add(tKey, tValue.ToString());
            } else {
                if (defaultValue != null) {
                    myDict.Add(tKey, defaultValue.ToString());
                }
            }
        }

        public static void SetFontBoldOrNormal(Range row, tpFont tpFontTo) {
            SetFontBoldOrNormal(row, tpFontTo, false);
        }

        public static void SetFontBoldOrNormal(Range row, tpFont tpFontTo, bool isSummenZeile) {
            if (row == null) {
                return;
            }
            try {

                if (tpFontTo == tpFont.Bold & isSummenZeile) {
                    row.Font.Name = tpFontBold;
                    row.Font.Bold = true;
                } else {
                    row.Font.Bold = (tpFontTo == tpFont.Bold ? true : false);
                }
            } finally {
                //do nothing
            }
        }

        #endregion

    }
}
